UMAP Plots
Fig 1i
DimPlot(RPM_Orgs_Allo, group.by='Sample',cols=sample_cols, reduction='umap',
label=FALSE, label.size=6, shuffle=TRUE, pt.size=0.01) & NoAxes()

FeaturePlot(RPM_Orgs_Allo, features = c("NE_Consensus1"),
pt.size=0.2, reduction='umap', order=TRUE) +
ggplot2::scale_color_gradientn(colors=rocket(10, direction=-1)) & NoAxes()

FeaturePlot(RPM_Orgs_Allo, features = c("Basal_Consensus1"),
pt.size=0.2, reduction='umap',order=TRUE) +
ggplot2::scale_color_gradientn(colors=rocket(10, direction=-1)) & NoAxes()

Fig 1j
Violin plots of expression of TFs by Leiden cluster
genes <- c("Ascl1","Neurod1","Pou2f3","Atoh1","Yap1","Trp63")
# Create violin plots with Kruskal-Wallis test
plots <- lapply(genes, function(gene) {
p <- VlnPlot(RPM_Orgs_Allo,
features = gene,
group.by = "leiden_scVI_1.3",
cols = my_colors,
alpha = 0.5) + # smaller dots
ggpubr::stat_compare_means(method = "kruskal.test",
label = "p.format",
label.x = 2,size = 5) +
ggtitle("") +
theme(plot.title = element_text(face = "italic"), legend.position = "none", # Remove legend
axis.title.x = element_blank(),axis.title.y = element_text(size = 20),
axis.text.y = element_text(size = 20), axis.text.x = element_text(size = 14)) + # Remove x-axis label
labs(y = "Expression") # Change y-axis label to "Expression"
return(p)
})
# Arrange plots
patchwork::wrap_plots(plots, ncol = 6)

UMAP Plots by Sample and Cluster
Extended Data Fig 4a
DimPlot(RPM_Orgs, group.by='Genotype', cols=c("darkorchid4","orange"), reduction='umap',
label=FALSE, label.size=6, shuffle=TRUE) & NoAxes()

DimPlot(RPM_Orgs, group.by='cluster', cols=colors_figED4a, reduction='umap',
label=TRUE, label.size=10) & NoAxes()

Extended Data Fig 4c
DimPlot(RPM_Orgs, reduction = "umap", group.by = "Phase",
shuffle=TRUE, label=FALSE, pt.size=.05,
cols=c("indianred3","green3","royalblue4")) + NoAxes()

Ext. Data Fig. 4d
DimPlot(RPM_Orgs_Allo, reduction = "umap", group.by = "Phase",
shuffle=TRUE, label=FALSE, pt.size=.05,
cols=c("indianred3","green3","royalblue4")) + NoAxes()

# Plot barplot for Ext. Data Fig. 4d #
##### What % of cells per phase in each group? ####
x <- table(Idents(RPM_Orgs_Allo),RPM_Orgs_Allo@meta.data$Phase)
proportions <- as.data.frame(100*prop.table(x, margin = 1))
colnames(proportions)<-c("Cluster", "Sample", "Frequency")
# ggbarplot(proportions, x="Sample", y="Frequency", fill = "Sample", group = "Sample", ylab = "Frequency (percent)", xlab="Phase", palette =c("indianred3","green3","royalblue4"))+ theme_bw()+ facet_wrap(facets = "Cluster", scales="free_y", ncol =4)+ theme(axis.text.y = element_text(size=12)) +rotate_x_text(angle = 45)
# Stacked
p<-ggplot(proportions, aes(fill=Sample, y=Frequency, x=Cluster)) +
geom_bar(position="stack", stat="identity")
p + scale_fill_manual(values=c("indianred3","green3","royalblue4")) +
theme_bw() +
theme(axis.text.y = element_text(size=20), axis.text.x=element_text(size=20,angle=45, hjust = 1),
axis.title.x = element_text(size=20), axis.title.y = element_text(size=20),
legend.text = element_text(size=20), legend.title = element_text(size=20)) +
labs(x=NULL, y="Frequency (%)", fill=NULL)

Fig 1j
DimPlot(RPM_Allo, group.by='leiden_scVI_1.3', cols=my_colors,
reduction='umap', label=TRUE, label.size=7) & NoAxes() + theme(legend.position="none")

UMAP by Fate
Fig. 1k
pheno_col<-c("brown2","darkorchid4","dodgerblue","#66A61E","orange","turquoise4")
DimPlot(RPM_Allo, group.by=c("Pheno"), cols=pheno_col, shuffle=TRUE, pt.size=0.6)+NoAxes()

Fig 1l
# Fig 2g plots #
FeaturePlot(RPM_Allo, features = c("NE_spearman"), pt.size=0.2,
reduction='umap', order=TRUE) +
scale_color_viridis(option="rocket",direction=-1) & NoAxes()

Violin plots of Archetypes by leiden cluster
Ext. Data Fig. 4f
VlnPlot(
RPM_Allo,
features = c("A_Archetype1","A2_Archetype1","N_Archetype1","P_Archetype1"),
group.by = "leiden_scVI_1.3",
cols = my_colors,
alpha = 0.7,
ncol = 2
) &
theme(
axis.text.x = element_text(size = 8), # smaller x-axis labels
plot.title = element_text(face = "bold", size=0), # italicize titles
axis.title.x = element_text(size = 24), # optional size tweaks
axis.title.y = element_text(size = 24)
) &
labs(
y = "Expression",
x = "Cluster"
)

Plot Signature Scores by Phenotype
phenotypes <- as.character(unique(RPM_Allo$Pheno))
pheno_pairs_list <- combn(phenotypes, 2, simplify = FALSE)
Define function to plot violin plots by phenotype
plotVlnByPhen <- function(feature, yl=c(-0.1,0.3), focus=NA) {
if(!is.na(focus)) {
pheno_pairs_list <- pheno_pairs_list[sapply(pheno_pairs_list, function(x) focus %in% x)]
}
scater::plotColData(sce, x = "Pheno", y = feature, colour_by = "Pheno") +
scale_discrete_manual(aesthetics = c("colour", "fill"), values=pheno_col) +
theme(axis.title.y = element_text(size = 24), axis.text.y = element_text(size = 16),
axis.text.x = element_blank(), # rotate x-axis labels
plot.title = element_blank(), # remove plot title
legend.position = "none" # remove legend
) + labs(x = "", # custom x-axis title
y = "Signature score" # custom y-axis title
) + ylim(yl[1], yl[2]) +
geom_boxplot(fill=pheno_col, alpha=1/5, position = position_dodge(width = .2),
size=0.2, color="black", notch=TRUE, notchwidth=0.3, outlier.shape = 2, outlier.colour=NA) # +
# stat_summary(fun = mean,
# geom = "point",
# shape = 18,
# size = 2,
# color = "red",
# position = position_dodge(width = 0.5)) +
# ggpubr::stat_compare_means(method = "wilcox.test", label = "p.signif", size=4,
# vjust = 0.5,
# hide.ns = TRUE, comparisons = pheno_pairs_list)
}
Fig 1l
NE correlation
plotVlnByPhen("NE_spearman", yl=c(-.75, .8), focus="NE")

Fig 1m
SCLC cell type consensus signature scores * NE cell * Tuft cell *
Basal cell
plotVlnByPhen("NE_Consensus1", yl=c(-0.5, 1))

plotVlnByPhen("Tuft_Consensus1", yl=c(-0.1, 0.5))

plotVlnByPhen("Basal_Consensus1", yl=c(-0.1, 1.1))

Fig 1n
TF target gene scores * ASCL1 targets * NEUROD1 targets * ATOH1
targets * POU2F3 targets * YAP1 activity score
plotVlnByPhen("ASCL1_Targets1", yl=c(-0.1,0.6))

plotVlnByPhen("NEUROD1_Targets1", yl=c(-0.1,0.25))

plotVlnByPhen("ATOH1_Targets1", yl=c(-0.1,.3))

plotVlnByPhen("POU2F3_Targets1", yl=c(-0.1, 0.22))

plotVlnByPhen("YAP1_Activity_Score1", yl=c(-0.1, 1))

LS0tCnRpdGxlOiAiV1QgUlBNIE9yZ2Fub2lkcyBBbGxvZ3JhZnRzIE5vdGVib29rIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKZGF0ZTogMjAyNS0wNi0xNgphdXRob3I6ICJBYmJpZSBJcmVsYW5kLCBEYXJyZW4gVHlzb24iCi0tLQoKTW9kaWZ5aW5nIFtPcmlnaW5hbCBmaWxlIChGaWcyX0V4dEZpZzRfV1RfUlBNX09yZ2Fub2lkc19BbGxvZ3JhZnRzX0ZpbmFsLlIpXShQcmVwcm9jZXNzaW5nX2Zvcl9yZWZlcmVuY2UvUl9Db2RlL0ZpZzJfRXh0RmlnNF9XVF9SUE1fT3JnYW5vaWRzX0FsbG9ncmFmdHNfRmluYWwuUikgaW50byBhbiBleGVjdXRhYmxlIFJNYXJrZG93biBOb3RlYm9vawoKIyMjIFJlbGF0ZWQgdG86CiogRmlnIDFpLW4KKiBFeHRlbmRlZCBEYXRhIEZpZyA0YS1mCgpgYGB7cn0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKHsKICAgIGxpYnJhcnkodmlyaWRpcykKICAgIGxpYnJhcnkoZ2dwbG90MikKICAgIGxpYnJhcnkoc2NhdGVyKQogICAgbGlicmFyeShTZXVyYXQpCiAgICBsaWJyYXJ5KGdncHVicikKfSkKYGBgCgojIyMjIERlZmluZSBjb2xvcnMgZm9yIGZpZ3VyZXMKYGBge3J9CiMgRGVmaW5lIGNvbG9yIHNjaGVtZSBhbmQgcGxvdCBVTUFQIGFzIGluIEZpZy4gMmUgIwpteV9jb2xvcnMgPC0gYygKICAiI0U0MUExQyIsICMgc3Ryb25nIHJlZAogICIjMzc3RUI4IiwgIyBtZWRpdW0gYmx1ZQogICIjNERBRjRBIiwgIyBncmVlbgogICIjOTg0RUEzIiwgIyBwdXJwbGUKICAiI0ZGN0YwMCIsICMgb3JhbmdlCiAgIiNGRkZGMzMiLCAjIHllbGxvdwogICIjQTY1NjI4IiwgIyBicm93bgogICIjZTcyOThhIiwgIyBwaW5rCiAgIiM2NjY2NjYiLCAjIGdyZXkKICAibGF2ZW5kZXIiLCAjIHRlYWwKICAiI0ZDOEQ2MiIsICMgc2FsbW9uCiAgIiM4REEwQ0IiLCAjIHNvZnQgYmx1ZQogICIjRTc4QUMzIiwgIyBzb2Z0IHBpbmsgKGRpZmZlcmVudCBmcm9tIDgpCiAgIiNBNkQ4NTQiLCAjIGxpZ2h0IGdyZWVuIChidXQgeWVsbG93aXNoIHRpbnQsIG5vdCBncmVlbikKICAiI0ZGRDkyRiIsICMgbGVtb24geWVsbG93CiAgIiNFNUM0OTQiLCAjIGxpZ2h0IGJyb3duCiAgIiNCM0IzQjMiLCAjIGxpZ2h0IGdyZXkKICAiIzFCOUU3NyIsICMgZGVlcCB0ZWFsCiAgIiNEOTVGMDIiLCAjIGRhcmsgb3JhbmdlCiAgIiM3NTcwQjMiLCAjIHN0cm9uZyBwdXJwbGUKICAidHVycXVvaXNlIiAgIyBvbGl2ZSBncmVlbiAoTk9UIHNhbWUgZ3JlZW4gYXMgYmVmb3JlKQopCgpjb2xvcnNfZmlnRUQ0YSA8LSBjKCdkZWVwc2t5Ymx1ZTQnLCAnI0ZDOEQ2MicsJyMyY2EwMmMnLCAnYnJvd24xJywgJ3B1cnBsZScsICcjQTA1MjJEJywKICAgICAgICAgICAgICAgICAgICAncGluazInLCAgJyNhMWMyOTknLCAgJyMwYWE2ZDgnLCAnbGlnaHRibHVlJywnc2FsbW9uMScsJ2xpZ2h0Z3JlZW4nKQoKc2FtcGxlX2NvbHM8LWMoIm9yYW5nZSIsIiNEOEJGRDgiLCJkYXJrb3JjaGlkNCIsICMgZGVlcCB0ZWFsCiAgICAgICAgICAgICAgICJ0dXJxdW9pc2UiLCAiIzFCOUU3NyIgIyBkYXJrIG9yYW5nZQopCgpwaGVub19jb2w8LWMoImJyb3duMiIsImRhcmtvcmNoaWQ0IiwiZG9kZ2VyYmx1ZSIsIiM2NkE2MUUiLCJvcmFuZ2UiLCJ0dXJxdW9pc2U0IikKCmBgYAoKCiMjIyBMb2FkIFJQTSBPcmdhbm9pZHMgZGF0YQpgYGB7cn0KUlBNX09yZ3MgPC0gcmVhZFJEUygiLi4vZGF0YS8wNV8yMDI1X1JQTV9PcmdzX09ubHlfRXh0RmlnNGEtYy5yZHMiKQpgYGAKCiMjIyBMb2FkIENlbGxUYWdnZWQgT3JnYW5vaWQgQWxsb2dyYWZ0cyBkYXRhCmBgYHtyfQpSUE1fT3Jnc19BbGxvIDwtIHJlYWRSRFMoIi4uL2RhdGEvMDVfMjAyNV9SUE1fT3Jnc19BbGxvX0ZpZzJkLnJkcyIpCmBgYAoKIyMjIExvYWQgUlBNIGFsbG9ncmFmdC1vbmx5IGRhdGEKYGBge3J9ClJQTV9BbGxvIDwtIHJlYWRSRFMoIi4uL2RhdGEvMDVfMjAyNV9SUE1fQWxsb2dyYWZ0T25seV9GaWcyZS5yZHMiKQpgYGAKCiMjIyBMb2FkIFJQTSBhbGxvZ3JhZnRzIGFzIFNpbmdsZUNlbGxFeHBlcmltZW50CmBgYHtyfQpzY2UgPC0gcmVhZFJEUygnLi4vZGF0YS9SUE1fQWxsb19vbmx5X3NjZS5yZHMnKQpgYGAKCgojIyMgVU1BUCBQbG90cwojIyMjICoqRmlnIDFpKioKYGBge3J9CkRpbVBsb3QoUlBNX09yZ3NfQWxsbywgIGdyb3VwLmJ5PSdTYW1wbGUnLGNvbHM9c2FtcGxlX2NvbHMsIHJlZHVjdGlvbj0ndW1hcCcsCiAgICAgICAgbGFiZWw9RkFMU0UsIGxhYmVsLnNpemU9Niwgc2h1ZmZsZT1UUlVFLCBwdC5zaXplPTAuMDEpICYgTm9BeGVzKCkKYGBgCgoKYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KRmVhdHVyZVBsb3QoUlBNX09yZ3NfQWxsbywgZmVhdHVyZXMgPSBjKCJORV9Db25zZW5zdXMxIiksIAogICAgICAgICAgICBwdC5zaXplPTAuMiwgcmVkdWN0aW9uPSd1bWFwJywgb3JkZXI9VFJVRSkgKyAKICAgIGdncGxvdDI6OnNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvcnM9cm9ja2V0KDEwLCBkaXJlY3Rpb249LTEpKSAmIE5vQXhlcygpCgpGZWF0dXJlUGxvdChSUE1fT3Jnc19BbGxvLCBmZWF0dXJlcyA9IGMoIkJhc2FsX0NvbnNlbnN1czEiKSwgCiAgICAgICAgICAgIHB0LnNpemU9MC4yLCByZWR1Y3Rpb249J3VtYXAnLG9yZGVyPVRSVUUpICsgCiAgICBnZ3Bsb3QyOjpzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3JzPXJvY2tldCgxMCwgZGlyZWN0aW9uPS0xKSkgJiBOb0F4ZXMoKQpgYGAKIyMjIyBGaWcgMWoKVmlvbGluIHBsb3RzIG9mIGV4cHJlc3Npb24gb2YgVEZzIGJ5IExlaWRlbiBjbHVzdGVyCmBgYHtyIGZpZy5oZWlnaHQ9My41LCBmaWcud2lkdGg9MTUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmdlbmVzIDwtIGMoIkFzY2wxIiwiTmV1cm9kMSIsIlBvdTJmMyIsIkF0b2gxIiwiWWFwMSIsIlRycDYzIikKCiMgQ3JlYXRlIHZpb2xpbiBwbG90cyB3aXRoIEtydXNrYWwtV2FsbGlzIHRlc3QKcGxvdHMgPC0gbGFwcGx5KGdlbmVzLCBmdW5jdGlvbihnZW5lKSB7CiAgcCA8LSBWbG5QbG90KFJQTV9PcmdzX0FsbG8sCiAgICAgICAgICAgICAgIGZlYXR1cmVzID0gZ2VuZSwKICAgICAgICAgICAgICAgZ3JvdXAuYnkgPSAibGVpZGVuX3NjVklfMS4zIiwKICAgICAgICAgICAgICAgY29scyA9IG15X2NvbG9ycywKICAgICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsgICMgc21hbGxlciBkb3RzCiAgICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAia3J1c2thbC50ZXN0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAicC5mb3JtYXQiLCAKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbC54ID0gMixzaXplID0gNSkgKwogICAgZ2d0aXRsZSgiIikgKwogICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gIml0YWxpYyIpLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsICAjIFJlbW92ZSBsZWdlbmQKICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSxheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpICsgICMgUmVtb3ZlIHgtYXhpcyBsYWJlbAogICAgbGFicyh5ID0gIkV4cHJlc3Npb24iKSAgIyBDaGFuZ2UgeS1heGlzIGxhYmVsIHRvICJFeHByZXNzaW9uIgogIHJldHVybihwKQp9KQoKIyBBcnJhbmdlIHBsb3RzCnBhdGNod29yazo6d3JhcF9wbG90cyhwbG90cywgbmNvbCA9IDYpCmBgYAoKCiMjIyBVTUFQIFBsb3RzIGJ5IFNhbXBsZSBhbmQgQ2x1c3RlcgojIyMjICoqRXh0ZW5kZWQgRGF0YSBGaWcgNGEqKgpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LjV9CkRpbVBsb3QoUlBNX09yZ3MsIGdyb3VwLmJ5PSdHZW5vdHlwZScsIGNvbHM9YygiZGFya29yY2hpZDQiLCJvcmFuZ2UiKSwgcmVkdWN0aW9uPSd1bWFwJywKICAgICAgICBsYWJlbD1GQUxTRSwgbGFiZWwuc2l6ZT02LCBzaHVmZmxlPVRSVUUpICYgTm9BeGVzKCkKYGBgCmBgYHtyIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTQuNX0KCkRpbVBsb3QoUlBNX09yZ3MsIGdyb3VwLmJ5PSdjbHVzdGVyJywgY29scz1jb2xvcnNfZmlnRUQ0YSwgcmVkdWN0aW9uPSd1bWFwJywKICAgICAgICBsYWJlbD1UUlVFLCBsYWJlbC5zaXplPTEwKSAmIE5vQXhlcygpCgpgYGAKIyMjIyAqKkV4dGVuZGVkIERhdGEgRmlnIDRjKioKYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NC43NX0KRGltUGxvdChSUE1fT3JncywgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJQaGFzZSIsCiAgICAgICAgc2h1ZmZsZT1UUlVFLCBsYWJlbD1GQUxTRSwgcHQuc2l6ZT0uMDUsIAogICAgICAgIGNvbHM9YygiaW5kaWFucmVkMyIsImdyZWVuMyIsInJveWFsYmx1ZTQiKSkgKyBOb0F4ZXMoKQpgYGAKCiMjIyMgRXh0LiBEYXRhIEZpZy4gNGQgCmBgYHtyIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTV9CkRpbVBsb3QoUlBNX09yZ3NfQWxsbywgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJQaGFzZSIsCiAgICAgICAgc2h1ZmZsZT1UUlVFLCBsYWJlbD1GQUxTRSwgcHQuc2l6ZT0uMDUsIAogICAgICAgIGNvbHM9YygiaW5kaWFucmVkMyIsImdyZWVuMyIsInJveWFsYmx1ZTQiKSkgKyBOb0F4ZXMoKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTR9CiMgUGxvdCBiYXJwbG90IGZvciBFeHQuIERhdGEgRmlnLiA0ZCAjCiMjIyMjIFdoYXQgJSBvZiBjZWxscyBwZXIgcGhhc2UgaW4gZWFjaCBncm91cD8gIyMjIwp4IDwtIHRhYmxlKElkZW50cyhSUE1fT3Jnc19BbGxvKSxSUE1fT3Jnc19BbGxvQG1ldGEuZGF0YSRQaGFzZSkKcHJvcG9ydGlvbnMgPC0gYXMuZGF0YS5mcmFtZSgxMDAqcHJvcC50YWJsZSh4LCBtYXJnaW4gPSAxKSkKCmNvbG5hbWVzKHByb3BvcnRpb25zKTwtYygiQ2x1c3RlciIsICJTYW1wbGUiLCAiRnJlcXVlbmN5IikKCiMgZ2diYXJwbG90KHByb3BvcnRpb25zLCB4PSJTYW1wbGUiLCB5PSJGcmVxdWVuY3kiLCBmaWxsID0gIlNhbXBsZSIsIGdyb3VwID0gIlNhbXBsZSIsIHlsYWIgPSAiRnJlcXVlbmN5IChwZXJjZW50KSIsIHhsYWI9IlBoYXNlIiwgcGFsZXR0ZSA9YygiaW5kaWFucmVkMyIsImdyZWVuMyIsInJveWFsYmx1ZTQiKSkrIHRoZW1lX2J3KCkrIGZhY2V0X3dyYXAoZmFjZXRzID0gIkNsdXN0ZXIiLCBzY2FsZXM9ImZyZWVfeSIsIG5jb2wgPTQpKyB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgK3JvdGF0ZV94X3RleHQoYW5nbGUgPSA0NSkKCiMgU3RhY2tlZApwPC1nZ3Bsb3QocHJvcG9ydGlvbnMsIGFlcyhmaWxsPVNhbXBsZSwgeT1GcmVxdWVuY3ksIHg9Q2x1c3RlcikpICsKICBnZW9tX2Jhcihwb3NpdGlvbj0ic3RhY2siLCBzdGF0PSJpZGVudGl0eSIpCgpwICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImluZGlhbnJlZDMiLCJncmVlbjMiLCJyb3lhbGJsdWU0IikpICsgCiAgICB0aGVtZV9idygpICsgCiAgICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSwgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9MjAsYW5nbGU9NDUsIGhqdXN0ID0gMSksIAogICAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemU9MjApLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCksIAogICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0yMCksIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSkgKwogICAgbGFicyh4PU5VTEwsIHk9IkZyZXF1ZW5jeSAoJSkiLCBmaWxsPU5VTEwpCgpgYGAKCgoKIyMjIyBGaWcgMWoKYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NX0KRGltUGxvdChSUE1fQWxsbywgZ3JvdXAuYnk9J2xlaWRlbl9zY1ZJXzEuMycsIGNvbHM9bXlfY29sb3JzLAogICAgICAgIHJlZHVjdGlvbj0ndW1hcCcsIGxhYmVsPVRSVUUsIGxhYmVsLnNpemU9NykgJiBOb0F4ZXMoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCmBgYAoKIyMjIFVNQVAgYnkgRmF0ZQojIyMjICoqRmlnLiAxayoqCmBgYHtyIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTZ9CnBoZW5vX2NvbDwtYygiYnJvd24yIiwiZGFya29yY2hpZDQiLCJkb2RnZXJibHVlIiwiIzY2QTYxRSIsIm9yYW5nZSIsInR1cnF1b2lzZTQiKQoKRGltUGxvdChSUE1fQWxsbywgZ3JvdXAuYnk9YygiUGhlbm8iKSwgY29scz1waGVub19jb2wsIHNodWZmbGU9VFJVRSwgcHQuc2l6ZT0wLjYpK05vQXhlcygpCmBgYAoKIyMjIyBGaWcgMWwKYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NS41LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIEZpZyAyZyBwbG90cyAjCkZlYXR1cmVQbG90KFJQTV9BbGxvLCBmZWF0dXJlcyA9IGMoIk5FX3NwZWFybWFuIiksIHB0LnNpemU9MC4yLCAKICAgICAgICAgICAgcmVkdWN0aW9uPSd1bWFwJywgb3JkZXI9VFJVRSkgKyAKICAgIHNjYWxlX2NvbG9yX3ZpcmlkaXMob3B0aW9uPSJyb2NrZXQiLGRpcmVjdGlvbj0tMSkgJiBOb0F4ZXMoKQpgYGAKCiMjIyBWaW9saW4gcGxvdHMgb2YgQXJjaGV0eXBlcyBieSBsZWlkZW4gY2x1c3RlcgojIyMjICoqRXh0LiBEYXRhIEZpZy4gNGYqKgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KVmxuUGxvdCgKICBSUE1fQWxsbywKICBmZWF0dXJlcyA9IGMoIkFfQXJjaGV0eXBlMSIsIkEyX0FyY2hldHlwZTEiLCJOX0FyY2hldHlwZTEiLCJQX0FyY2hldHlwZTEiKSwKICBncm91cC5ieSA9ICJsZWlkZW5fc2NWSV8xLjMiLAogIGNvbHMgPSBteV9jb2xvcnMsCiAgYWxwaGEgPSAwLjcsCiAgbmNvbCA9IDIKKSAmIAogIHRoZW1lKAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAgICAgICAgICAgICAgICAjIHNtYWxsZXIgeC1heGlzIGxhYmVscwogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplPTApLCAgICAgICAgICAjIGl0YWxpY2l6ZSB0aXRsZXMKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLCAgICAgICAgICAgICAgIyBvcHRpb25hbCBzaXplIHR3ZWFrcwogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCkKICApICYKICBsYWJzKAogICAgeSA9ICJFeHByZXNzaW9uIiwKICAgIHggPSAiQ2x1c3RlciIKICApCgpgYGAKCgojIyMgUGxvdCBTaWduYXR1cmUgU2NvcmVzIGJ5IFBoZW5vdHlwZQpgYGB7cn0KcGhlbm90eXBlcyA8LSBhcy5jaGFyYWN0ZXIodW5pcXVlKFJQTV9BbGxvJFBoZW5vKSkKcGhlbm9fcGFpcnNfbGlzdCA8LSBjb21ibihwaGVub3R5cGVzLCAyLCBzaW1wbGlmeSA9IEZBTFNFKQpgYGAKCiMjIyMgRGVmaW5lIGZ1bmN0aW9uIHRvIHBsb3QgdmlvbGluIHBsb3RzIGJ5IHBoZW5vdHlwZQpgYGB7cn0KcGxvdFZsbkJ5UGhlbiA8LSBmdW5jdGlvbihmZWF0dXJlLCB5bD1jKC0wLjEsMC4zKSwgZm9jdXM9TkEpIHsKICAgIGlmKCFpcy5uYShmb2N1cykpIHsKICAgICAgICBwaGVub19wYWlyc19saXN0IDwtIHBoZW5vX3BhaXJzX2xpc3Rbc2FwcGx5KHBoZW5vX3BhaXJzX2xpc3QsIGZ1bmN0aW9uKHgpIGZvY3VzICVpbiUgeCldCiAgICB9CiAgICAKICAgIHNjYXRlcjo6cGxvdENvbERhdGEoc2NlLCB4ID0gIlBoZW5vIiwgeSA9IGZlYXR1cmUsIGNvbG91cl9ieSA9ICJQaGVubyIpICsgCiAgICAgICAgc2NhbGVfZGlzY3JldGVfbWFudWFsKGFlc3RoZXRpY3MgPSBjKCJjb2xvdXIiLCAiZmlsbCIpLCB2YWx1ZXM9cGhlbm9fY29sKSArCiAgICAgICAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNCksIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiksCiAgICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksICAgIyByb3RhdGUgeC1heGlzIGxhYmVscwogICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksICAgICMgcmVtb3ZlIHBsb3QgdGl0bGUKICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIgICAgICAgICAjIHJlbW92ZSBsZWdlbmQKICAgICAgICApICsgbGFicyh4ID0gIiIsICAgICAgICAgICAgICAgICAgICAgIyBjdXN0b20geC1heGlzIHRpdGxlCiAgICAgICAgICAgICAgICAgeSA9ICJTaWduYXR1cmUgc2NvcmUiICAgICAgICAjIGN1c3RvbSB5LWF4aXMgdGl0bGUKICAgICAgICApICsgeWxpbSh5bFsxXSwgeWxbMl0pICsgCiAgICAgICAgZ2VvbV9ib3hwbG90KGZpbGw9cGhlbm9fY29sLCBhbHBoYT0xLzUsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuMiksCiAgICAgICAgICAgICAgICAgICAgIHNpemU9MC4yLCBjb2xvcj0iYmxhY2siLCBub3RjaD1UUlVFLCBub3RjaHdpZHRoPTAuMywgb3V0bGllci5zaGFwZSA9IDIsIG91dGxpZXIuY29sb3VyPU5BKSAjICAgKyAKICAgICAgICAjIHN0YXRfc3VtbWFyeShmdW4gPSBtZWFuLAogICAgICAgICMgICAgICAgICAgICAgIGdlb20gPSAicG9pbnQiLAogICAgICAgICMgICAgICAgICAgICAgIHNoYXBlID0gMTgsCiAgICAgICAgIyAgICAgICAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgIyAgICAgICAgICAgICAgY29sb3IgPSAicmVkIiwKICAgICAgICAjICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKyAKICAgICAgICAjIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIGxhYmVsID0gInAuc2lnbmlmIiwgc2l6ZT00LCAKICAgICAgICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZqdXN0ID0gMC41LAogICAgICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZS5ucyA9IFRSVUUsIGNvbXBhcmlzb25zID0gcGhlbm9fcGFpcnNfbGlzdCkKfQpgYGAKCgojIyMjIEZpZyAxbApORSBjb3JyZWxhdGlvbgpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD0yLjUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBsb3RWbG5CeVBoZW4oIk5FX3NwZWFybWFuIiwgeWw9YygtLjc1LCAuOCksIGZvY3VzPSJORSIpCmBgYAoKIyMjIyBGaWcgMW0KU0NMQyBjZWxsIHR5cGUgY29uc2Vuc3VzIHNpZ25hdHVyZSBzY29yZXMKKiBORSBjZWxsCiogVHVmdCBjZWxsCiogQmFzYWwgY2VsbApgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD0zLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwbG90VmxuQnlQaGVuKCJORV9Db25zZW5zdXMxIiwgeWw9YygtMC41LCAxKSkKcGxvdFZsbkJ5UGhlbigiVHVmdF9Db25zZW5zdXMxIiwgeWw9YygtMC4xLCAwLjUpKQpwbG90VmxuQnlQaGVuKCJCYXNhbF9Db25zZW5zdXMxIiwgeWw9YygtMC4xLCAxLjEpKQpgYGAKIyMjIyBGaWcgMW4KVEYgdGFyZ2V0IGdlbmUgc2NvcmVzCiogQVNDTDEgdGFyZ2V0cwoqIE5FVVJPRDEgdGFyZ2V0cwoqIEFUT0gxIHRhcmdldHMKKiBQT1UyRjMgdGFyZ2V0cwoqIFlBUDEgYWN0aXZpdHkgc2NvcmUKCmBgYHtyIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBsb3RWbG5CeVBoZW4oIkFTQ0wxX1RhcmdldHMxIiwgeWw9YygtMC4xLDAuNikpCnBsb3RWbG5CeVBoZW4oIk5FVVJPRDFfVGFyZ2V0czEiLCB5bD1jKC0wLjEsMC4yNSkpCnBsb3RWbG5CeVBoZW4oIkFUT0gxX1RhcmdldHMxIiwgeWw9YygtMC4xLC4zKSkKcGxvdFZsbkJ5UGhlbigiUE9VMkYzX1RhcmdldHMxIiwgeWw9YygtMC4xLCAwLjIyKSkKcGxvdFZsbkJ5UGhlbigiWUFQMV9BY3Rpdml0eV9TY29yZTEiLCB5bD1jKC0wLjEsIDEpKQpgYGAKCg==